Micron Document
<!DOCTYPE html>
<html class="client-nojs vector-feature-language-in-header-enabled vector-feature-language-in-main-page-header-disabled vector-feature-page-tools-pinned-disabled vector-feature-toc-pinned-clientpref-0 vector-toc-not-available vector-feature-main-menu-pinned-disabled vector-feature-limited-width-clientpref-1 vector-feature-limited-width-content-enabled vector-feature-custom-font-size-clientpref-1 vector-feature-appearance-pinned-clientpref-0 skin-theme-clientpref-day vector-sticky-header-enabled" lang="de" dir="ltr"><head>
<meta charset="UTF-8">
<title>Hierarchisches Layout</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" href="./_res_/favicon.png">
<link rel="canonical" href="https://de.wikipedia.org/wiki/Hierarchisches_Layout"> <link href="./_mw_/ext.pygments.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.wikimediamessages.styles.css" rel="stylesheet" type="text/css">
<link href="./_mw_/skins.vector.icons.css" rel="stylesheet" type="text/css">
<link href="./_mw_/skins.vector.search.codex.styles.css" rel="stylesheet" type="text/css">
<link href="./_mw_/skins.vector.styles.css" rel="stylesheet" type="text/css">
<meta name="ResourceLoaderDynamicStyles" content="">
<link href="./_mw_/ext.gadget.citeRef.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.defaultPlainlinks.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.dewikiCommonHide.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.dewikiCommonLayout.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.dewikiCommonStyle.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.dewikiDarkmode.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.dewikiResponsive.css" rel="stylesheet" type="text/css">
<link href="./_mw_/ext.gadget.specialSearch.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" type="text/css" href="./_mw_/site.styles.css">
<link rel="stylesheet" type="text/css" href="./_mw_/noscript.css">
<link rel="stylesheet" type="text/css" href="./_res_/footer.css">
<link rel="stylesheet" type="text/css" href="./_res_/vector-2022.css">
</head>
<body class="skin--responsive skin-vector skin-vector-search-vue mediawiki ltr sitedir-ltr mw-hide-empty-elt ns-0 ns-subject page-Hierarchisches_Layout rootpage-Hierarchisches_Layout skin-vector-2022 action-view">
<div class="mw-page-container">
<div class="mw-page-container-inner">
<div class="mw-content-container">
<main id="content" class="mw-body">
<header class="mw-body-header vector-page-titlebar">
<h1 id="firstHeading" class="firstHeading mw-first-heading"><span class="mw-page-title-main">Hierarchisches Layout</span></h1>
</header>
<a id="top"></a>
<div id="bodyContent" class="vector-body ve-init-mw-desktopArticleTarget-targetContainer" aria-labelledby="firstHeading" data-mw-ve-target-container="">
<div id="contentSub">
<div id="mw-content-subtitle"></div>
</div>
<div id="mw-content-text" class="mw-body-content mw-content-ltr" lang="de" dir="ltr"><div class="mw-content-ltr mw-parser-output" lang="de" dir="ltr">
<p>Die Entwicklung von <b>Algorithmen für hierarchisches Layout</b> ist ein Themengebiet der <a href="Informatik" title="Informatik">Informatik</a> und beschäftigt sich mit der Definition von Berechnungsvorschriften zum Layout und <a href="Graphzeichnen" title="Graphzeichnen">Zeichnen hierarchischer Graphen</a>. Die Berechnung des Layouts und das Zeichnen der Graphen kann statisch (das Layout wird in einem Durchlauf berechnet und gezeichnet) oder dynamisch (es wird ein Start-Layout berechnet und in mehreren Durchläufen optimiert und gezeichnet) erfolgen.
</p>

<div class="mw-heading mw-heading2"><h2 id="Grundlagen">Grundlagen</h2></div>

<p>In seiner reinen Form ist der hierarchische Graph ein gerichteter Graph und hat eine Quelle (Knoten ohne eingehende Kanten) sowie mehrere Senken (Knoten ohne ausgehende Kanten). Die zwischen Quelle und Senke liegenden Knoten können abhängig von ihrer Entfernung von der Quelle in <a href="%C3%84quivalenzklasse" class="mw-redirect" title="Äquivalenzklasse">Äquivalenzklassen</a> unterteilt werden.
</p>
<div class="mw-heading mw-heading2"><h2 id="Layoutansätze"><span id="Layoutans.C3.A4tze"></span>Layoutansätze</h2></div>
<p>Um die Charakteristik eines hierarchischen Graphen herauszuarbeiten, bieten sich zwei Ansätze für das Layout, also die Anordnung der Knoten und Kanten des Graphen zueinander, an.
</p>
<div class="mw-heading mw-heading3"><h3 id="Eiskristall">Eiskristall</h3></div>

<p>Ein hierarchisches Layout als Eiskristall ermöglicht viele unterschiedliche konkrete Ausprägungen bei i. d. R. geringem Flächenverbrauch gegenüber einem Layout als Baum, kann aber keine Ordnung zwischen Knoten derselben Äquivalenzebene darstellen.
</p><p>Bei diesem Layoutansatz steht die Quelle im Mittelpunkt und alle Knoten einer Äquivalenzklasse haben den gleichen Abstand vom Knoten der übergeordneten Äquivalenzklasse. Die konkrete Ausprägung des Layouts unterscheidet sich einerseits dadurch, ob
</p>
<ul><li>alle Kanten im Graph die gleiche Länge aufweisen,</li>
<li>alle Kanten zu Knoten einer definierten Äquivalenzebene die gleiche Länge aufweisen, aber alle Kanten zu Knoten der untergeordneten Äquivalenzebene eine andere, untereinander wieder gleiche Länge aufweisen oder</li>
<li>alle Kanten im Graph eine unterschiedliche Länge aufweisen</li></ul>
<p>und andererseits dadurch, ob
</p>
<ul><li>Knoten einer untergeordneten Äquivalenzebene nur von der Quelle weg angeordnet werden oder</li>
<li>in jeder beliebigen Richtung angeordnet werden.</li></ul>
<p>Der einfachste statische Algorithmus für Eiskristall-Layout berechnet die Anordnung der Knoten auf konzentrischen Kreisen um die Quelle. Er ermittelt das Gewicht jedes Knotens anhand der Anzahl der mit ihm verbundenen Knoten aller untergeordneten Äquivalenzebenen. Dieses Gewicht ist dann Maß für den Winkel, den der Knoten auf dem seiner Äquivalenzebenen zugeordneten konzentrischen Kreis beansprucht. Sowohl die Berechnung des Gewichts der Knoten als auch das Zeichnen von Knoten und Kanten wird durch rekursive Methodenaufrufe realisiert. Für das Zeichnen muss darüber hinaus ein Startwinkel festgelegt werden.
</p>
<div class="mw-heading mw-heading4"><h4 id="Implementierung">Implementierung</h4></div>
<p>Die folgende Klasse gibt ein Beispiel für die <a href="Implementierung" title="Implementierung">Implementierung</a> einer Node-Klasse in C#, anhand derer man die Funktionsweise gut nachvollziehen kann.
</p>
<div class="mw-highlight mw-highlight-lang-csharp mw-content-ltr" dir="ltr"><pre><span></span><span class="w"> </span><span class="k">public</span><span class="w"> </span><span class="k">class</span><span class="w"> </span><span class="nc">GraphNode</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">public</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">Int32</span><span class="w"> </span><span class="n">NodeRadius</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">10</span><span class="p">;</span><span class="w"> </span><span class="c1">// Draw node as point, use radius = 10.</span>

<span class="w"> </span><span class="k">public</span><span class="w"> </span><span class="n">List</span><span class="o">&lt;</span><span class="n">GraphNode</span><span class="o">&gt;</span><span class="w"> </span><span class="n">Children</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">List</span><span class="o">&lt;</span><span class="n">GraphNode</span><span class="o">&gt;</span><span class="p">();</span><span class="w"> </span><span class="c1">// Every node circa have 0..N child nodes.</span>

<span class="w"> </span><span class="k">public</span><span class="w"> </span><span class="n">Int32</span><span class="w"> </span><span class="n">Level</span><span class="p">;</span><span class="w"> </span><span class="c1">// Define the level of equivalence.</span>
<span class="w"> </span><span class="k">public</span><span class="w"> </span><span class="n">Int32</span><span class="w"> </span><span class="n">Weight</span><span class="p">;</span><span class="w"> </span><span class="c1">// Store the aggregated weight.</span>

<span class="w"> </span><span class="k">private</span><span class="w"> </span><span class="nf">GraphNode</span><span class="p">()</span><span class="w"> </span><span class="c1">// Prevent default constructor calls.</span>
<span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">;</span><span class="w"> </span><span class="p">}</span>

<span class="w"> </span><span class="k">public</span><span class="w"> </span><span class="nf">GraphNode</span><span class="p">(</span><span class="n">Int32</span><span class="w"> </span><span class="n">level</span><span class="p">)</span><span class="w"> </span><span class="c1">// Initializing constructor.</span>
<span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">Level</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">level</span><span class="p">;</span><span class="w"> </span><span class="p">}</span>

<span class="w"> </span><span class="k">public</span><span class="w"> </span><span class="n">Int32</span><span class="w"> </span><span class="nf">CalculateWeight</span><span class="p">()</span><span class="w"> </span><span class="c1">// Calculate weight recursively.</span>
<span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">Children</span><span class="p">.</span><span class="n">Count</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="n">Weight</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="n">Weight</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>

<span class="w"> </span><span class="k">foreach</span><span class="w"> </span><span class="p">(</span><span class="n">GraphNode</span><span class="w"> </span><span class="n">child</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">Children</span><span class="p">)</span><span class="w"> </span><span class="n">Weight</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">child</span><span class="p">.</span><span class="n">CalculateWeight</span><span class="p">();</span>

<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">Weight</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>

<span class="w"> </span><span class="k">private</span><span class="w"> </span><span class="n">Int32</span><span class="w"> </span><span class="nf">X</span><span class="p">(</span><span class="n">Graphics</span><span class="w"> </span><span class="n">g</span><span class="p">,</span><span class="w"> </span><span class="kt">double</span><span class="w"> </span><span class="n">angle</span><span class="p">,</span><span class="w"> </span><span class="kt">double</span><span class="w"> </span><span class="n">radius</span><span class="p">)</span><span class="w"> </span><span class="c1">// Calculate x-position on concentric circle.</span>
<span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">(</span><span class="n">Int32</span><span class="p">)((</span><span class="n">g</span><span class="p">.</span><span class="n">VisibleClipBounds</span><span class="p">.</span><span class="n">Width</span><span class="p">)</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">Math</span><span class="p">.</span><span class="n">Cos</span><span class="p">(</span><span class="n">angle</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">radius</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">Level</span><span class="p">);</span><span class="w"> </span><span class="p">}</span>

<span class="w"> </span><span class="k">private</span><span class="w"> </span><span class="n">Int32</span><span class="w"> </span><span class="nf">Y</span><span class="p">(</span><span class="n">Graphics</span><span class="w"> </span><span class="n">g</span><span class="p">,</span><span class="w"> </span><span class="kt">double</span><span class="w"> </span><span class="n">angle</span><span class="p">,</span><span class="w"> </span><span class="kt">double</span><span class="w"> </span><span class="n">radius</span><span class="p">)</span><span class="w"> </span><span class="c1">// Calculate y-position on concentric circle.</span>
<span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">(</span><span class="n">Int32</span><span class="p">)((</span><span class="n">g</span><span class="p">.</span><span class="n">VisibleClipBounds</span><span class="p">.</span><span class="n">Height</span><span class="p">)</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">Math</span><span class="p">.</span><span class="n">Sin</span><span class="p">(</span><span class="n">angle</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">radius</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">Level</span><span class="p">);</span><span class="w"> </span><span class="p">}</span>

<span class="w"> </span><span class="k">public</span><span class="w"> </span><span class="k">void</span><span class="w"> </span><span class="nf">DrawEqualAngle</span><span class="p">(</span><span class="n">Graphics</span><span class="w"> </span><span class="n">g</span><span class="p">,</span><span class="w"> </span><span class="kt">double</span><span class="w"> </span><span class="n">radius</span><span class="p">,</span><span class="w"> </span><span class="kt">double</span><span class="w"> </span><span class="n">start</span><span class="p">,</span><span class="w"> </span><span class="kt">double</span><span class="w"> </span><span class="n">share</span><span class="p">,</span><span class="w"> </span><span class="n">Rectangle</span><span class="w"> </span><span class="n">parent</span><span class="p">)</span>
<span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">Brush</span><span class="w"> </span><span class="n">brush</span><span class="p">;</span>
<span class="w"> </span><span class="n">Pen</span><span class="w"> </span><span class="n">pen</span><span class="p">;</span>
<span class="w"> </span><span class="n">Double</span><span class="w"> </span><span class="n">angle</span><span class="p">;</span>
<span class="w"> </span><span class="n">Rectangle</span><span class="w"> </span><span class="n">rect</span><span class="p">;</span>

<span class="w"> </span><span class="n">angle</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">start</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">Weight</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">share</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">2</span><span class="p">;</span><span class="w"> </span><span class="c1">// Calculate angle of this node.</span>
<span class="w"> </span><span class="n">rect</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">Rectangle</span><span class="p">(</span><span class="n">X</span><span class="p">(</span><span class="n">g</span><span class="p">,</span><span class="w"> </span><span class="n">angle</span><span class="p">,</span><span class="w"> </span><span class="n">radius</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">NodeRadius</span><span class="p">,</span><span class="w"> </span><span class="c1">// Calculate position of this node.</span>
<span class="w"> </span><span class="n">Y</span><span class="p">(</span><span class="n">g</span><span class="p">,</span><span class="w"> </span><span class="n">angle</span><span class="p">,</span><span class="w"> </span><span class="n">radius</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">NodeRadius</span><span class="p">,</span>
<span class="w"> </span><span class="n">NodeRadius</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="n">NodeRadius</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mi">2</span><span class="p">);</span>

<span class="w"> </span><span class="k">foreach</span><span class="w"> </span><span class="p">(</span><span class="n">GraphNode</span><span class="w"> </span><span class="n">child</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">Children</span><span class="p">)</span><span class="w"> </span><span class="c1">// Draw child nodes.</span>
<span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">child</span><span class="p">.</span><span class="n">DrawEqualAngle</span><span class="p">(</span><span class="n">g</span><span class="p">,</span><span class="w"> </span><span class="n">radius</span><span class="p">,</span><span class="w"> </span><span class="n">start</span><span class="p">,</span><span class="w"> </span><span class="n">share</span><span class="p">,</span><span class="w"> </span><span class="n">rect</span><span class="p">);</span>
<span class="w"> </span><span class="n">start</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">share</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">child</span><span class="p">.</span><span class="n">Weight</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>

<span class="w"> </span><span class="n">brush</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">SolidBrush</span><span class="p">((</span><span class="n">Level</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="n">Color</span><span class="p">.</span><span class="n">DarkBlue</span><span class="w"> </span><span class="p">:</span>
<span class="w"> </span><span class="p">(</span><span class="n">Level</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="n">Color</span><span class="p">.</span><span class="n">DarkGreen</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="n">Color</span><span class="p">.</span><span class="n">DarkRed</span><span class="p">)));</span>
<span class="w"> </span><span class="n">pen</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">Pen</span><span class="p">(</span><span class="n">brush</span><span class="p">);</span>

<span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="n">DrawLine</span><span class="p">(</span><span class="n">pen</span><span class="p">,</span><span class="w"> </span><span class="n">parent</span><span class="p">.</span><span class="n">Left</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">parent</span><span class="p">.</span><span class="n">Width</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="c1">// Draw this node's connection to parent.</span>
<span class="w"> </span><span class="n">parent</span><span class="p">.</span><span class="n">Top</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">parent</span><span class="p">.</span><span class="n">Height</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span>
<span class="w"> </span><span class="n">rect</span><span class="p">.</span><span class="n">Left</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">rect</span><span class="p">.</span><span class="n">Width</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="n">rect</span><span class="p">.</span><span class="n">Top</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">rect</span><span class="p">.</span><span class="n">Height</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">2</span><span class="p">);</span>
<span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="n">FillEllipse</span><span class="p">(</span><span class="n">brush</span><span class="p">,</span><span class="w"> </span><span class="n">rect</span><span class="p">);</span><span class="w"> </span><span class="c1">// Draw this node.</span>

<span class="w"> </span><span class="n">pen</span><span class="p">.</span><span class="n">Dispose</span><span class="p">();</span>
<span class="w"> </span><span class="n">brush</span><span class="p">.</span><span class="n">Dispose</span><span class="p">();</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
</pre></div>
<p>Die folgende Methode gibt ein Beispiel für die <a href="Implementierung" title="Implementierung">Implementierung</a> des vollständigen Zeichnens in C#, wobei die Methoden der Node-Klasse für die Berechnung des Gewichtes und das Zeichnen aufgerufen werden.
</p>
<div class="mw-highlight mw-highlight-lang-csharp mw-content-ltr" dir="ltr"><pre><span></span><span class="w"> </span><span class="k">private</span><span class="w"> </span><span class="k">void</span><span class="w"> </span><span class="nf">PaintEqualAngle</span><span class="p">()</span>
<span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">Int32</span><span class="w"> </span><span class="n">totalWeight</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="w"> </span><span class="n">Double</span><span class="w"> </span><span class="n">startAngle</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="w"> </span><span class="n">Graphics</span><span class="w"> </span><span class="n">g</span><span class="p">;</span>
<span class="w"> </span><span class="n">Brush</span><span class="w"> </span><span class="n">brush</span><span class="p">;</span>
<span class="w"> </span><span class="n">Rectangle</span><span class="w"> </span><span class="n">rect</span><span class="p">;</span>

<span class="w"> </span><span class="k">foreach</span><span class="w"> </span><span class="p">(</span><span class="n">GraphNode</span><span class="w"> </span><span class="n">node</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">Graph</span><span class="p">)</span><span class="w"> </span><span class="c1">// Calculate maximum weight.</span>
<span class="w"> </span><span class="n">totalWeight</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="n">CalculateWeight</span><span class="p">();</span>

<span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="n">CreateGraphics</span><span class="p">();</span>
<span class="w"> </span><span class="n">brush</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">SolidBrush</span><span class="p">(</span><span class="n">BackColor</span><span class="p">);</span>
<span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="n">FillRectangle</span><span class="p">(</span><span class="n">brush</span><span class="p">,</span><span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="n">VisibleClipBounds</span><span class="p">);</span><span class="w"> </span><span class="c1">// Clear background.</span>
<span class="w"> </span><span class="n">brush</span><span class="p">.</span><span class="n">Dispose</span><span class="p">();</span>

<span class="w"> </span><span class="n">rect</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">Rectangle</span><span class="p">((</span><span class="n">Int32</span><span class="p">)((</span><span class="n">g</span><span class="p">.</span><span class="n">VisibleClipBounds</span><span class="p">.</span><span class="n">Width</span><span class="p">)</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">GraphNode</span><span class="p">.</span><span class="n">NodeRadius</span><span class="p">,</span>
<span class="w"> </span><span class="p">(</span><span class="n">Int32</span><span class="p">)((</span><span class="n">g</span><span class="p">.</span><span class="n">VisibleClipBounds</span><span class="p">.</span><span class="n">Height</span><span class="p">)</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">GraphNode</span><span class="p">.</span><span class="n">NodeRadius</span><span class="p">,</span>
<span class="w"> </span><span class="n">GraphNode</span><span class="p">.</span><span class="n">NodeRadius</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="n">GraphNode</span><span class="p">.</span><span class="n">NodeRadius</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mi">2</span><span class="p">);</span>

<span class="w"> </span><span class="k">foreach</span><span class="w"> </span><span class="p">(</span><span class="n">GraphNode</span><span class="w"> </span><span class="n">node</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">Graph</span><span class="p">)</span><span class="w"> </span><span class="c1">// Draw child nodes.</span>
<span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="n">DrawEqualAngle</span><span class="p">(</span><span class="n">g</span><span class="p">,</span><span class="w"> </span><span class="n">Math</span><span class="p">.</span><span class="n">Min</span><span class="p">(</span><span class="n">g</span><span class="p">.</span><span class="n">VisibleClipBounds</span><span class="p">.</span><span class="n">Width</span><span class="p">,</span><span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="n">VisibleClipBounds</span><span class="p">.</span><span class="n">Height</span><span class="p">)</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">7</span><span class="p">,</span>
<span class="w"> </span><span class="n">startAngle</span><span class="p">,</span><span class="w"> </span><span class="n">Math</span><span class="p">.</span><span class="n">PI</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">totalWeight</span><span class="p">,</span><span class="w"> </span><span class="n">rect</span><span class="p">);</span>
<span class="w"> </span><span class="n">startAngle</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">Math</span><span class="p">.</span><span class="n">PI</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">totalWeight</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="n">Weight</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>

<span class="w"> </span><span class="n">brush</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">SolidBrush</span><span class="p">(</span><span class="n">Color</span><span class="p">.</span><span class="n">Black</span><span class="p">);</span>
<span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="n">FillEllipse</span><span class="p">(</span><span class="n">brush</span><span class="p">,</span><span class="w"> </span><span class="n">rect</span><span class="p">);</span><span class="w"> </span><span class="c1">// Draw root.</span>
<span class="w"> </span><span class="n">brush</span><span class="p">.</span><span class="n">Dispose</span><span class="p">();</span>
<span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="n">Dispose</span><span class="p">();</span>
<span class="w"> </span><span class="p">}</span>
</pre></div>
<div class="mw-heading mw-heading3"><h3 id="Baum">Baum</h3></div>

<p>Ein hierarchisches Layout als Baum ermöglicht die Darstellung einer Ordnung zwischen Knoten derselben Äquivalenzebene (z. B. durch horizontale oder vertikale Anordnung), beansprucht aber i. d. R. mehr Fläche als ein Layout als Eiskristall.
</p><p>Bei diesem Layoutansatz ist eine Richtung (z. B. von oben nach unten) vorgegeben, in der sich der Graph ausbreitet. Alle Knoten einer Äquivalenzklasse liegen auf derselben Ebene. Die konkrete Ausprägung des Layouts wird gekennzeichnet durch die Entwicklungsrichtung (horizontal oder vertikal) je Äquivalenzebene.
</p><p>Der einfachste statische Algorithmus für Baum-Layout berechnet die Anordnung der Knoten auf allen Äquivalenzebenen in derselben, z. B. horizontalen, Entwicklungsrichtung. Er ermittelt das Gewicht jedes Knotens anhand der Anzahl der mit ihm verbundenen Knoten aller untergeordneten Äquivalenzebenen. Dieses Gewicht ist dann Maß für den Anteil, den der Knoten auf der seiner Äquivalenzebenen zugeordneten Entwicklungsrichtung beansprucht. Sowohl die Berechnung des Gewichts der Knoten als auch das Zeichnen von Knoten und Kanten wird durch rekursive Methodenaufrufe realisiert.
</p>
<div class="mw-heading mw-heading4"><h4 id="Implementierung_2">Implementierung</h4></div>
<p>Die folgende Methode gibt ein Beispiel einer <a href="Implementierung" title="Implementierung">Implementierung</a> zur Erweiterung der Node-Klasse in C#, anhand derer man die Funktionsweise gut nachvollziehen kann.
</p>
<div class="mw-highlight mw-highlight-lang-csharp mw-content-ltr" dir="ltr"><pre><span></span><span class="w"> </span><span class="k">public</span><span class="w"> </span><span class="k">void</span><span class="w"> </span><span class="nf">DrawHorizontalTree</span><span class="p">(</span><span class="n">Graphics</span><span class="w"> </span><span class="n">g</span><span class="p">,</span><span class="w"> </span><span class="kt">double</span><span class="w"> </span><span class="n">distance</span><span class="p">,</span><span class="w"> </span><span class="kt">double</span><span class="w"> </span><span class="n">start</span><span class="p">,</span><span class="w"> </span><span class="kt">double</span><span class="w"> </span><span class="n">share</span><span class="p">,</span><span class="w"> </span><span class="n">Rectangle</span><span class="w"> </span><span class="n">parent</span><span class="p">)</span>
<span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">Brush</span><span class="w"> </span><span class="n">brush</span><span class="p">;</span>
<span class="w"> </span><span class="n">Pen</span><span class="w"> </span><span class="n">pen</span><span class="p">;</span>
<span class="w"> </span><span class="n">Double</span><span class="w"> </span><span class="n">position</span><span class="p">;</span>
<span class="w"> </span><span class="n">Rectangle</span><span class="w"> </span><span class="n">rect</span><span class="p">;</span>

<span class="w"> </span><span class="n">position</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">start</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">Weight</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">share</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">2</span><span class="p">;</span><span class="w"> </span><span class="c1">// Calculate angle of this node.</span>
<span class="w"> </span><span class="n">rect</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">Rectangle</span><span class="p">((</span><span class="n">Int32</span><span class="p">)(</span><span class="n">position</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">NodeRadius</span><span class="p">),</span><span class="w"> </span><span class="c1">// Calculate position of this node.</span>
<span class="w"> </span><span class="p">(</span><span class="n">Int32</span><span class="p">)(</span><span class="n">distance</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="n">Level</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">NodeRadius</span><span class="p">),</span>
<span class="w"> </span><span class="n">NodeRadius</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="n">NodeRadius</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mi">2</span><span class="p">);</span>

<span class="w"> </span><span class="k">foreach</span><span class="w"> </span><span class="p">(</span><span class="n">GraphNode</span><span class="w"> </span><span class="n">child</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">Children</span><span class="p">)</span><span class="w"> </span><span class="c1">// Draw child nodes.</span>
<span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">child</span><span class="p">.</span><span class="n">DrawHorizontalTree</span><span class="p">(</span><span class="n">g</span><span class="p">,</span><span class="w"> </span><span class="n">distance</span><span class="p">,</span><span class="w"> </span><span class="n">start</span><span class="p">,</span><span class="w"> </span><span class="n">share</span><span class="p">,</span><span class="w"> </span><span class="n">rect</span><span class="p">);</span>
<span class="w"> </span><span class="n">start</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">share</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">child</span><span class="p">.</span><span class="n">Weight</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>

<span class="w"> </span><span class="n">brush</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">SolidBrush</span><span class="p">((</span><span class="n">Level</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="n">Color</span><span class="p">.</span><span class="n">DarkBlue</span><span class="w"> </span><span class="p">:</span>
<span class="w"> </span><span class="p">(</span><span class="n">Level</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="n">Color</span><span class="p">.</span><span class="n">DarkGreen</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="n">Color</span><span class="p">.</span><span class="n">DarkRed</span><span class="p">)));</span>
<span class="w"> </span><span class="n">pen</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">Pen</span><span class="p">(</span><span class="n">brush</span><span class="p">);</span>

<span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="n">DrawLine</span><span class="p">(</span><span class="n">pen</span><span class="p">,</span><span class="w"> </span><span class="n">parent</span><span class="p">.</span><span class="n">Left</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">parent</span><span class="p">.</span><span class="n">Width</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="c1">// Draw this node's connection to parent.</span>
<span class="w"> </span><span class="n">parent</span><span class="p">.</span><span class="n">Top</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">parent</span><span class="p">.</span><span class="n">Height</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span>
<span class="w"> </span><span class="n">rect</span><span class="p">.</span><span class="n">Left</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">rect</span><span class="p">.</span><span class="n">Width</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="n">rect</span><span class="p">.</span><span class="n">Top</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">rect</span><span class="p">.</span><span class="n">Height</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">2</span><span class="p">);</span>
<span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="n">FillEllipse</span><span class="p">(</span><span class="n">brush</span><span class="p">,</span><span class="w"> </span><span class="n">rect</span><span class="p">);</span><span class="w"> </span><span class="c1">// Draw this node.</span>

<span class="w"> </span><span class="n">pen</span><span class="p">.</span><span class="n">Dispose</span><span class="p">();</span>
<span class="w"> </span><span class="n">brush</span><span class="p">.</span><span class="n">Dispose</span><span class="p">();</span>
<span class="w"> </span><span class="p">}</span>
</pre></div>
<p>Die folgende Methode gibt ein Beispiel für die <a href="Implementierung" title="Implementierung">Implementierung</a> des vollständigen Zeichnens in C#, wobei die Methoden der Node-Klasse für die Berechnung des Gewichtes und das Zeichnen aufgerufen werden.
</p>
<div class="mw-highlight mw-highlight-lang-csharp mw-content-ltr" dir="ltr"><pre><span></span><span class="w"> </span><span class="k">private</span><span class="w"> </span><span class="k">void</span><span class="w"> </span><span class="nf">PaintHorizontalTree</span><span class="p">()</span>
<span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">Int32</span><span class="w"> </span><span class="n">totalWeight</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="w"> </span><span class="n">Double</span><span class="w"> </span><span class="n">startWidth</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="w"> </span><span class="n">Graphics</span><span class="w"> </span><span class="n">g</span><span class="p">;</span>
<span class="w"> </span><span class="n">Brush</span><span class="w"> </span><span class="n">brush</span><span class="p">;</span>
<span class="w"> </span><span class="n">Rectangle</span><span class="w"> </span><span class="n">rect</span><span class="p">;</span>

<span class="w"> </span><span class="k">foreach</span><span class="w"> </span><span class="p">(</span><span class="n">GraphNode</span><span class="w"> </span><span class="n">node</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">Graph</span><span class="p">)</span><span class="w"> </span><span class="c1">// Calculate maximum weight.</span>
<span class="w"> </span><span class="n">totalWeight</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="n">CalculateWeight</span><span class="p">();</span>

<span class="w"> </span><span class="n">g</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="n">CreateGraphics</span><span class="p">();</span>
<span class="w"> </span><span class="n">brush</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">SolidBrush</span><span class="p">(</span><span class="n">BackColor</span><span class="p">);</span>
<span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="n">FillRectangle</span><span class="p">(</span><span class="n">brush</span><span class="p">,</span><span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="n">VisibleClipBounds</span><span class="p">);</span><span class="w"> </span><span class="c1">// Clear background.</span>
<span class="w"> </span><span class="n">brush</span><span class="p">.</span><span class="n">Dispose</span><span class="p">();</span>

<span class="w"> </span><span class="n">rect</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">Rectangle</span><span class="p">((</span><span class="n">Int32</span><span class="p">)((</span><span class="n">g</span><span class="p">.</span><span class="n">VisibleClipBounds</span><span class="p">.</span><span class="n">Width</span><span class="p">)</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">GraphNode</span><span class="p">.</span><span class="n">NodeRadius</span><span class="p">,</span>
<span class="w"> </span><span class="p">(</span><span class="n">Int32</span><span class="p">)((</span><span class="n">g</span><span class="p">.</span><span class="n">VisibleClipBounds</span><span class="p">.</span><span class="n">Height</span><span class="p">)</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">5</span><span class="p">)</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">GraphNode</span><span class="p">.</span><span class="n">NodeRadius</span><span class="p">,</span>
<span class="w"> </span><span class="n">GraphNode</span><span class="p">.</span><span class="n">NodeRadius</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="n">GraphNode</span><span class="p">.</span><span class="n">NodeRadius</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mi">2</span><span class="p">);</span>

<span class="w"> </span><span class="k">foreach</span><span class="w"> </span><span class="p">(</span><span class="n">GraphNode</span><span class="w"> </span><span class="n">node</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">Graph</span><span class="p">)</span><span class="w"> </span><span class="c1">// Draw child nodes.</span>
<span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="n">DrawHorizontalTree</span><span class="p">(</span><span class="n">g</span><span class="p">,</span><span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="n">VisibleClipBounds</span><span class="p">.</span><span class="n">Height</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">5</span><span class="p">,</span>
<span class="w"> </span><span class="n">startWidth</span><span class="p">,</span><span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="n">VisibleClipBounds</span><span class="p">.</span><span class="n">Width</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">totalWeight</span><span class="p">,</span><span class="w"> </span><span class="n">rect</span><span class="p">);</span>
<span class="w"> </span><span class="n">startWidth</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="n">VisibleClipBounds</span><span class="p">.</span><span class="n">Width</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">totalWeight</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="n">Weight</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>

<span class="w"> </span><span class="n">brush</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">SolidBrush</span><span class="p">(</span><span class="n">Color</span><span class="p">.</span><span class="n">Black</span><span class="p">);</span>
<span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="n">FillEllipse</span><span class="p">(</span><span class="n">brush</span><span class="p">,</span><span class="w"> </span><span class="n">rect</span><span class="p">);</span><span class="w"> </span><span class="c1">// Draw root.</span>
<span class="w"> </span><span class="n">brush</span><span class="p">.</span><span class="n">Dispose</span><span class="p">();</span>
<span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="n">Dispose</span><span class="p">();</span>
<span class="w"> </span><span class="p">}</span>
</pre></div>
<div class="mw-heading mw-heading3"><h3 id="Anwendungen_hierarchischer_Layouts">Anwendungen hierarchischer Layouts</h3></div>
<p>Hierarchische Graphen eignen sich zur Darstellung von Strukturen ohne Zyklen (Rückschleifen und Zusammenführung von Teilpfaden) wie:
</p>
<ul><li><a href="Organigramm" title="Organigramm">Organigrammen</a></li>
<li><a href="Funktionsbaum" title="Funktionsbaum">Funktionsbäumen</a></li>
<li><a href="Syntaxbaum" title="Syntaxbaum">Syntaxbäumen</a></li></ul></div><!--htdig_noindex--><div><div class="zim-footer">
Dieser Artikel wurde von <a class="external text" title="Zuletzt bearbeitet am 2024-12-06" href="https://de.wikipedia.org/wiki/?title=Hierarchisches_Layout&amp;oldid=251000356">Wikipedia</a> herausgegeben. Der Text ist unter <a class="external text" href="https://creativecommons.org/licenses/by-sa/4.0/deed.de">Creative Commons Attribution-Share Alike 4.0</a> verfügbar, sofern nicht anders angegeben. Für die Mediendateien können zusätzliche Bedingungen gelten.
</div>
</div><!--/htdig_noindex--></div>
</div>
</main>
</div>
</div>
</div>
<script src="./_webp_/webpHandler.js"></script>

</body></html>